#include <sys/types.h> 
#include <sys/socket.h>
#include "UdpUnix.hpp"

UdpUnix::UdpUnix()
{
}

UdpUnix::~UdpUnix()
{
}

int UdpUnix::SetSockNonBlocking(int fd)
{
  timeval tv;
  unsigned int i;
  int ret;

  i = 1;
  tv.tv_sec = 0;
  tv.tv_usec = 10;
  setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, static_cast<void *>(&i), sizeof(i));
  ret = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, static_cast<void *>(&tv), sizeof(tv));
  return ret;
}

int           UdpUnix::Socket()
{
  int ret;

  ret = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
  return ret;
}

int UdpUnix::Bind(int fd,
		  SockInfo &si)
{
  int		len;
  SocketInfo	sin;
  int ret;

  sin = si.GetSin();
  len = sizeof(sin);
  ret = bind(fd, Convert<struct sockaddr *, SocketInfo *>(&sin), len);
  return ret;
}


int		UdpUnix::OpenSocket(int	&fdSocket)
{
  if ((fdSocket = Socket()) == -1)
    {
      puts("Can't open local socket.");
      return (-1);
    }
  return (0);
}

template<typename A, typename B>
A Convert(B t)
{
  return ((A)t);
}

int UdpUnix::SendTo(int	fd,
		    SockInfo si,
		    char *buf,
		    int	size)
{
  int len;
  SocketInfo sin;
  int ret;

  sin = si.GetSin();
  len = sizeof(si.GetSin());
  ret =  sendto(fd, static_cast<void *>(buf), size, MSG_NOSIGNAL, Convert<const struct sockaddr *>(&sin), Convert<socklen_t, int>(len));
  return ret;
}

int UdpUnix::RecvFrom(int	fd,
		      SockInfo si,
		      char	*buf,
		      int	size)
{
  int len;
  SocketInfo sin;
  int ret;

  sin = si.GetSin();
  len = sizeof(si.GetSin());
  ret = recvfrom(fd, static_cast<void *>(buf), size, 0, Convert<struct sockaddr *>(&sin), Convert<socklen_t *, int *>(&len));
  return ret;
}
